// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#include "mk_header.h"
#include "mk_particle_pool.h"
#include "mk_engine.h"
#include "mk_error.h"

namespace MK3DE
{
	CParticlePool::CParticlePool() :
		_particlePool(NULL),
		_freeSlotIdx(NULL),
		_poolSize(0),
		_freeSlotSize(0)
	{
	}

	CParticlePool::~CParticlePool()
	{
		DealocatePool();
	}

	BOOL CParticlePool::AllocatePool(DWORD maxCount)
	{
		_particlePool = new Particle[maxCount];
		MK_PROCESS_ERROR(_particlePool);

		_freeSlotIdx = new DWORD[maxCount];
		MK_PROCESS_ERROR(_freeSlotIdx);

		for (DWORD i = 0; i < maxCount; ++i)
			_freeSlotIdx[i] = i;

		_freeSlotSize = maxCount;
		_poolSize = maxCount;
		return TRUE;
	Exit0:
		DealocatePool();
		return FALSE;
	}

	void CParticlePool::DealocatePool()
	{
		SAFE_DELETE_ARRAY(_particlePool);
		SAFE_DELETE_ARRAY(_freeSlotIdx);
		_poolSize = 0;
		_freeSlotSize = 0;
	}

	BOOL CParticlePool::AllocateParticle(Particle*& particle, DWORD& idx)
	{
		if (_freeSlotSize == 0)
			return FALSE;

		idx = _freeSlotIdx[--_freeSlotSize];
		particle = _particlePool + idx;
		return TRUE;
	}

	BOOL CParticlePool::DeallocateParticle(DWORD& idx)
	{
		if (idx < _poolSize)
		{
			_freeSlotIdx[_freeSlotSize++] = idx;
			return TRUE;
		}

		return FALSE;
	}

	Particle* CParticlePool::GetParticle(DWORD idx)
	{
		if (idx < _poolSize)
			return _particlePool + idx;
		return NULL;
	}
}